package com.tianji.remark.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import lombok.RequiredArgsConstructor;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.tianji.common.constants.MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author WangXinyi
 * @since 2025-01-03
 */
//@Service
@RequiredArgsConstructor
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper mqHelper;

    /**
     * 点赞或取消赞
     *
     * @param recordDTO
     */
    @Override
    public void addLikeRecord(LikeRecordFormDTO recordDTO) {
        //判断是否是点赞
        if (recordDTO.getLiked()) {
            //是点赞，判断是否点过赞
            Integer count = lambdaQuery().eq(LikedRecord::getBizId, recordDTO.getBizId())
                    .eq(LikedRecord::getBizType, recordDTO.getBizType())
                    .eq(LikedRecord::getUserId, UserContext.getUser())
                    .count();
            if (count == 0) {
                //没有点过赞，新增点赞记录
                LikedRecord likedRecord = BeanUtil.toBean(recordDTO, LikedRecord.class);
                likedRecord.setUserId(UserContext.getUser());
                boolean result = save(likedRecord);
                if (!result) {
                    throw new DbException("添加点赞记录失败！");
                }
            } else {
                return;
            }
        } else {
            //不是点赞,判断是否点过赞
            Integer count = lambdaQuery().eq(LikedRecord::getBizId, recordDTO.getBizId())
                    .eq(LikedRecord::getBizType, recordDTO.getBizType())
                    .eq(LikedRecord::getUserId, UserContext.getUser())
                    .count();
            if (count > 0) {
                //点过赞，删除点赞记录
                LambdaQueryWrapper<LikedRecord> eq = Wrappers.<LikedRecord>lambdaQuery().eq(LikedRecord::getBizId, recordDTO.getBizId())
                        .eq(LikedRecord::getBizType, recordDTO.getBizType())
                        .eq(LikedRecord::getUserId, UserContext.getUser());
                boolean remove = remove(eq);
                if (!remove) {
                    throw new DbException("删除点赞记录失败！");
                }
            } else {
                return;
            }
        }
        // 如果执行成功，统计点赞总数
        Integer likedTimes = lambdaQuery()
                .eq(LikedRecord::getBizId, recordDTO.getBizId())
                .count();
        // 发送MQ通知
        mqHelper.send(
                MqConstants.Exchange.LIKE_RECORD_EXCHANGE,
                StringUtils.format(LIKED_TIMES_KEY_TEMPLATE, recordDTO.getBizType()),
                new LikedTimesDTO(recordDTO.getBizId(), likedTimes));
    }


    /**
     * 查询指定业务id的点赞状态
     */
    @Override
    public Set<Long> isBizLiked(List<Long> bizIds) {
        if (CollUtil.isEmpty(bizIds)) {
            return Collections.emptySet();
        }
        //1.获取用户id
        Long userId = UserContext.getUser();
        // 2.查询点赞状态
        List<LikedRecord> list = lambdaQuery()
                .in(LikedRecord::getBizId, bizIds)
                .eq(LikedRecord::getUserId, userId)
                .list();
        // 3.返回结果
        return list.stream().map(LikedRecord::getBizId).collect(Collectors.toSet());
    }
}
